package yxy.apple.http.request;

import java.util.Enumeration;
import java.util.Hashtable;

import yxy.apple.http.HTTPException;
import yxy.apple.util.http.HTTPProtocol.Method;

public abstract class HTTPRequest<BodyContentType> {
	private Method method = Method.Get;
	private String url = null;
	private String redirectedUrl = null;
	private Hashtable<String, String> headers = new Hashtable<String, String>();
	private BodyContentType body = null;
	private boolean gzipSupported = false;

	public HTTPRequest(Method method, String url) {
		this.method = method;
		this.url = url;
	}

	public Method method() {
		return method;
	}

	public String url() {
		return url;
	}

	public String redirectedUrl() {
		return redirectedUrl;
	}

	@Deprecated
	public void redirect(String location) {
		this.redirectedUrl = location;
	}

	public Enumeration<String> allHeaderKeys() {
		return headers.keys();
	}

	public String getHeaderValue(String key) {
		return this.headers.get(key);
	}

	public void setHeader(String key, String value) {
		this.headers.put(key, value);
	}

	public BodyContentType body() {
		return body;
	}

	public void setBody(BodyContentType body) {
		this.body = body;
	}

	public boolean gzipSupported() {
		return gzipSupported;
	}

	public void setGzipSupported(boolean supported) {
		this.gzipSupported = supported;
	}

	@Override
	public String toString() {
		StringBuffer buffer = new StringBuffer();
		buffer.append(this.methodLineToString(this.method, this.url));
		buffer.append("\r\n");
		buffer.append(this.headersToString(this.headers));
		buffer.append("\r\n");
		buffer.append("\r\n");
		String content = this.bodyToString(this.body);
		if (content != null) {
			buffer.append(content);
			//buffer.append("\r\n");
		}
		return buffer.toString();
	}

	protected String methodLineToString(Method method, String url) {
		StringBuffer buffer = new StringBuffer();
		buffer.append(method.toString());
		buffer.append(" ");
		buffer.append(url);
		return buffer.toString();
	}

	protected String headersToString(Hashtable<String, String> headers) {
		StringBuffer buffer = new StringBuffer();
		Enumeration<String> keys = headers.keys();
		while (keys.hasMoreElements()) {
			String key = keys.nextElement();
			buffer.append(key);
			buffer.append(": ");
			buffer.append(headers.get(key));
			if (keys.hasMoreElements()) {
				buffer.append("\r\n");
			}
		}
		return buffer.toString();
	}

	protected abstract String bodyToString(BodyContentType body);

	public abstract byte[] encodedBody() throws HTTPException;
}
